﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using PluginRunner.API;

namespace PluginRunner
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            var directory = Directory.GetDirectories(Path.GetDirectoryName(Application.ExecutablePath), "Plugins").First();
            var pluginNames = Directory.GetFiles(directory, "*.dll");
            List<Type> pluginTypes = new List<Type>();
            foreach (string path in pluginNames)
            {
                //if (IsPlugin(path))
                //{
                pluginTypes.AddRange(GetPlugins(path));
                //}
            }

            foreach (Type type in pluginTypes)
            {
                var entryPoints = CreatePlugins(type);
                if (entryPoints.Count > 0)
                {
                    var item = new ToolStripMenuItem
                    {
                        Text = type.Name,
                        Size = new System.Drawing.Size(152, 22),
                    };
                    runToolStripMenuItem.DropDownItems.Insert(0, item);
                    for(int i = 0; i < entryPoints.Count; i++)
                    item.DropDownItems.Insert(0, new XtraMenuItem
                    {
                        Text = i.ToString(),
                        Clicker = entryPoints[i],
                        Size = new System.Drawing.Size(152, 22),
                    });
                }
                //var entryPoints = (from m in methods
                //                   select m);
            }

            //var plugins = (from  path in pluginNames
            //                  where IsPlugin(path)
            //                  select new {Name = Path.GetFileName(path), Run = CreatePlugin(path)});
            //foreach (var plugin in plugins)
            //{
            //    runToolStripMenuItem.DropDownItems.Insert(0, new XtraMenuItem
            //    {
            //        Text = plugin.Name,
            //        Clicker = plugin.Run,
            //        Size = new System.Drawing.Size(152, 22),
            //    });
            //}
        }

        bool IsPlugin(string path)
        {
            try
            {
                MethodInfo methodInfo = GetRunMethodInfo(GetPlugins(path).First()).First();
                return methodInfo != null;
            }
            catch
            {
                return false;
            }
        }

        IList<MethodInfo> GetRunMethodInfo(Type type)
        {
            var methods = type.GetMethods().Where(m =>
            {
                return m.GetCustomAttributes(typeof(IsEntryPointAttribute), true).Count() > 0;
            });
            return methods.ToList();
        }

        IList<Type> GetPlugins(string path)
        {
            var assembly = Assembly.LoadFile(path);
            var types = assembly.GetTypes().Where((type) => type.GetCustomAttributes(typeof(IsPluginAttribute), true).Count() > 0);
            return types.ToList();
        }

        IList<Func<object>> CreatePlugins(Type type)
        {
            IList<MethodInfo> methodInfos = GetRunMethodInfo(type);
            IList<Func<object>> result = new List<Func<object>>();
            foreach (MethodInfo mi in methodInfos)
            {
                result.Add(delegate
                {
                    object res = mi.Invoke(null, new object[] { this.Text });
                    return res;
                });
            }
            return result;
        }


        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
